package com.ruoyi.project.mahjong.controller.api;

import cn.hutool.Hutool;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.interceptor.annotation.RepeatSubmit;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.framework.web.domain.Result;
import com.ruoyi.project.mahjong.domain.*;
import com.ruoyi.project.mahjong.domain.dto.*;
import com.ruoyi.project.mahjong.domain.enu.TablenumberState;
import com.ruoyi.project.mahjong.domain.vo.TOpenTableVo;
import com.ruoyi.project.mahjong.mapper.DeskIngMapper;
import com.ruoyi.project.mahjong.service.*;
import com.ruoyi.project.mahjong.service.task.ChargTask;
import com.ruoyi.project.system.domain.SysUser;
import io.swagger.annotations.*;
import io.swagger.models.auth.In;
import org.apache.commons.collections4.Get;
import org.apache.ibatis.annotations.Param;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.github.pagehelper.page.PageMethod.startPage;

/**
 * 开桌相关操作
 */

@RestController
@RequestMapping("/mahjong/costs")
@Api(tags = "开桌相关操作api")
public class TableCostApiController {
    @Autowired
    private ITMemberService memberService;
    @Autowired
    private ITMemberService tMemberService;
    @Autowired
    private ITTablenumberService tTablenumberService;
    @Autowired
    private ITOpenTableService openTableService;
    @Autowired
    private ITOpenMoneyService itOpenMoneyService;
    @Autowired
    private ITRecordService recordService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ITTablenumberService tablenumberService;
    @Autowired
    private ChargTask chargTask;
    @Autowired
    private IDeskIngService deskIngService;
    @Autowired
    private DeskIngMapper deskIngMapper;

    /**
     * 按照会员名称模糊搜索
     *
     * @return
     */
    @GetMapping("/test/{tableId}")
    @ApiOperation(value = "按照会员名称模糊搜索", httpMethod = "GET")
    public Result<TMember> open(@ApiParam("姓名") @PathVariable("tableId") Long  tableId) {

        try {
            tablenumberService.openEnergize(tableId);
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.success();
    }
    /**
     * 按照会员名称模糊搜索
     *
     * @return
     */
    @GetMapping("/testclose/{tableId}")
    @ApiOperation(value = "按照会员名称模糊搜索", httpMethod = "GET")
    public Result<TMember> testclose(@ApiParam("姓名") @PathVariable("tableId") Long  tableId) {

        try {
            tablenumberService.closeEnergize(tableId);
        }catch (Exception e){
            e.printStackTrace();
        }
        return Result.success();
    }

    /**
     * 进行开房
     *
     * @param openTableIng 开房数据
     *                     insertTOpenTableAndIdInfo :新增开桌数据和店铺id和员工id
     * @return
     */
    @PostMapping("/openRoomTable")
    @ApiOperation(value = "进行开房", httpMethod = "POST")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "tOpenTable", value = "开房数据", dataType = "新开桌对象实体类字段", required = true),
            @ApiImplicitParam(name = "roomId", value = "房间id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "tableId", value = "桌子id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "costType", value = "消费类型id", dataType = "String", required = true),
            @ApiImplicitParam(name = "openStartTimes", value = "开桌时间", dataType = "String", required = true),
            @ApiImplicitParam(name = "remark", value = "备注", dataType = "String", required = true),
            @ApiImplicitParam(name = "tMember", value = "会员信息集合", dataType = "会员信息实体类字段", required = true),
            @ApiImplicitParam(name = "id", value = "会员id tMember", dataType = "Long", required = true),
    })
    @RepeatSubmit
    public Result<TOpenTableVo> openRoomTable(@RequestBody OpenTableIng openTableIng) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        openTableIng.setShopId(shopId);
        openTableIng.setStaffId(user.getUserId());

        try {
//电源打开
            tablenumberService.openEnergize(openTableIng.getTOpenTable().getTableId());
        }catch (Exception e){
            e.printStackTrace();
        }
//        开桌
        String status = openTableService.insertTOpenTableAndIdInfo(openTableIng);
        return Result.success(status);
    }

    /**
     * 按照会员名称模糊搜索
     *
     * @param name
     * @return
     */
    @GetMapping("/likeMemberName/{name}")
    @ApiOperation(value = "按照会员名称模糊搜索", httpMethod = "GET")
    public Result<TMember> likeMemberName(@ApiParam("姓名") @PathVariable("name") String name) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        List<TMember> memberList = tMemberService.selectMemberByLikeName(name, shopId);
        return Result.success(memberList);
    }

    /**
     * 设置为默认计费方式
     *
     * @return
     */
    @GetMapping("/Default/{costId}")
    @ApiOperation(value = "设置为默认计费方式", httpMethod = "GET")
    public Result<TMember> Default(@ApiParam("计费id") @PathVariable("costId") Long costId) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        Integer i = recordService.updateDefault(costId, shopId);
        return Result.success(i == 0 ? "设置默认失败" : "已设置为默认");
    }

    /**
     * 修改开桌备注
     *
     * @param tableRemark
     * @return
     */
    @PostMapping("/update/remark")
    @ApiOperation(value = "修改开桌备注", httpMethod = "POST")
    public Result updateOpenTableRemark(@RequestBody OpenTableRemark tableRemark) {
        //根据订单编号找到开桌信息
        DeskIng ing = deskIngMapper.selectByOrderSn(tableRemark.getOrderNumber());
        if (ObjectUtil.isNull(ing)) {
            return Result.error("开桌订单不存在，请重试");
        }
        ing.setRemark(tableRemark.getRemark());
        deskIngMapper.updateDeskIng(ing);
        return Result.success(ing);
    }

    /**
     * 查询开桌详情
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/getOpenTableInfo/{orderNumber}")
    @ApiOperation(value = "查询开桌详情", httpMethod = "GET")
    public Result<TOpenTableVo> getOpenTableInfo(@ApiParam("开桌订单编号") @PathVariable("orderNumber") String orderNumber) {
//       根据订单编号找到开房信息
        TOpenTableVo tOpenTable = openTableService.getOpenTableInfo(orderNumber);
        if (ObjectUtil.isNull(tOpenTable)) {
            return Result.error("查询失败，请重试");
        }
        return Result.success(tOpenTable);
    }

    /**
     * 停止计费
     *
     * @param orderNumber
     * @return
     */
    @PutMapping("/stop/billing/{orderNumber}")
    @ApiOperation(value = "停止计费", httpMethod = "POST")
    public Result tableStopBilling(@ApiParam("开桌订单编号") @PathVariable("orderNumber") String orderNumber) {
        // 停止桌子计费
        openTableService.tableStopBilling(orderNumber);
        return Result.success();
    }

    /**
     * 开桌临时加人
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/addPerson/{orderNumber}/{id}")
    @ApiOperation(value = "开桌临时加人", httpMethod = "GET")
    public Result<TOpenTableVo> addPerson(@ApiParam("开桌订单编号") @PathVariable("orderNumber") String orderNumber,
                                          @ApiParam("会员id") @PathVariable("id") Long id) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        return Result.success(openTableService.addPerson(orderNumber, id, shopId, user.getUserId()));
    }

    /**
     * 修改开桌备注
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/updateRemark/{orderNumber}/{remark}")
    @ApiOperation(value = "修改开桌备注", httpMethod = "GET")
    public Result<TOpenTableVo> updateRemark(@ApiParam("订单编号") @PathVariable("orderNumber") String orderNumber,
                                             @ApiParam("备注信息") @PathVariable("remark") String remark) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());

        Integer i = openTableService.updateRemark(orderNumber, remark);
        return Result.success(i == 0 ? "修改失败" : "修改成功");
    }

    /**
     * 手动增加收入
     *
     * @return
     */
    @PostMapping("/addReceive")
    @ApiOperation(value = "手动增加收入", httpMethod = "POST")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "incomeType", value = "收款类型 1 线上  2线下其他 3会员卡内扣款  ", dataType = "Long", required = true),
            @ApiImplicitParam(name = "specificName", value = "收入名称", dataType = "String", required = true),
            @ApiImplicitParam(name = "money", value = "应收金额", dataType = "String", required = true),
            @ApiImplicitParam(name = "receiveMoney", value = "实收金额", dataType = "String", required = true),
            @ApiImplicitParam(name = "incomeRefundTime", value = "收款时间", dataType = "String", required = true),
    })
    @RepeatSubmit
    public Result<TOpenTableVo> addReceive(@RequestBody TRecord record) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        record.setShopId(shopId);
        record.setStaffId(user.getUserId());
        Integer i = recordService.addReceive(record);
        return Result.success(i == 0 ? "增加收入失败" : "增加收入成功");
    }

    /**
     * 开桌会员退出，单独结账
     *
     * @return
     */
    @PostMapping("/oneOverTable")
    @ApiOperation(value = "开桌时会员退出，单独结账", httpMethod = "GET")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderNumber", value = "订单编号", dataType = "String", required = true),
            @ApiImplicitParam(name = "shiReceiveMoney", value = "实收金额", dataType = "String", required = true),
            @ApiImplicitParam(name = "yingReceiveMoney", value = "应收金额", dataType = "String", required = true),
            @ApiImplicitParam(name = "memberId", value = "结束会员id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "payType", value = "1=线上 2=现金 3=会员账户扣款", dataType = "String", required = true),
    })
    @RepeatSubmit
    public Result<TOpenTableVo> oneOverTable(@RequestBody OneOverTableDto overTableDto) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        overTableDto.setShopId(shopId);
        overTableDto.setStaffId(user.getUserId());
        Integer i = openTableService.oneOverTable(overTableDto);
        return Result.success("结束成功,已单独结账");
    }

    /**
     * 首页所有房间数据
     *
     * @param
     * @return
     */
    @GetMapping("/Index")
    @ApiOperation(value = "开桌页面所有房间数据", httpMethod = "GET")

//    public Result<TRoom> tableIndex(@ApiParam("开桌状态 3 开桌中 0 未开桌")@PathVariable("isOpenIng") String isOpenIng)
    public Result<TRoom> tableIndex() {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        List<TRoom> indexData = openTableService.getIndexDataVo(shopId);
        if (ObjectUtil.isNull(indexData)) {
            return Result.error("当前店铺可能没有桌台信息");
        }

//       for (TRoom room : indexData) {
//                 List<TTablenumber> collect = room.gettTablenumbers().stream()
//                        .filter(table -> table.getStatus()
//                                .equals(isOpenIng))
//                                   .collect(Collectors.toList());
//                room.settTablenumbers(collect);
//            }
        return Result.success(indexData);
//
    }

    /**
     * 点击空闲房间需要的数据//开桌前
     *
     * @param
     * @return
     */
    @GetMapping("/clickOpen/{roomId}")
    @ApiOperation(value = "点击空闲房间需要的数据", httpMethod = "GET")
    public Result<OpenTableDto> open(@ApiParam("房间id") @PathVariable("roomId") String roomId) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        OpenTableDto openTableDto = openTableService.getOpenVo(shopId, roomId);
        return Result.success(openTableDto);
    }


    /**
     * 结束开桌操作
     *
     * @param overOpenTableDto
     * @return
     */
    @PostMapping("/overOpenTable")
    @ApiOperation(value = "结束开桌操作", httpMethod = "POST")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderNumber", value = "订单编号", dataType = "String", required = true),
    })
    @RepeatSubmit
    public Result overOpenTable(@RequestBody OverOpenTableDto overOpenTableDto) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        overOpenTableDto.setStaffId(user.getUserId());
        overOpenTableDto.setShopId(shopId);
        String overStatus = openTableService.overOpenTable(overOpenTableDto);
        return Result.success(overStatus);
    }

    /**
     * 商品购买功能
     *
     * @param tOpenMoney
     * @return
     */
    @PostMapping("/buyProduct")
    @ApiOperation(value = "商品购买", httpMethod = "POST")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderNumber", value = "订单编号", dataType = "String", required = true),
            @ApiImplicitParam(name = "buyNumber", value = "购买数量", dataType = "Long", required = true),
            @ApiImplicitParam(name = "productId", value = "商品id", dataType = "Long", required = true),
            @ApiImplicitParam(name = "payType 收款类型 1 线上  2线下其他 3会员卡内扣款  ", value = "支付方式", dataType = "Long", required = true),
            @ApiImplicitParam(name = "memberId", value = "会员id", dataType = "String", required = true),
            @ApiImplicitParam(name = "buyType", value = "购买属性 ：1 店内商品购买 2 店员代购", dataType = "String", required = true),
    })
    @RepeatSubmit
    public Result<String> buyProduct(@RequestBody TOpenMoney tOpenMoney) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        tOpenMoney.setShopId(shopId);
        tOpenMoney.setStaffId(user.getUserId());
        int i = itOpenMoneyService.insertTOpenMoney(tOpenMoney);
        String status = i == 0 ? "购买失败" : "购买成功";
        return Result.success(status);

    }

    /**
     * 取消开桌功能
     * 一定时间内取消开桌不计费
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/cancelOpenTable/{orderNumber}")
    @ApiOperation(value = "取消开桌功能", httpMethod = "GET")
    public Result cancelOpenTable(@ApiParam(name = "orderNumber", value = "订单id", required = true) @PathVariable("orderNumber") String orderNumber) {

        return Result.success(openTableService.cancelOpenTable(orderNumber));
    }

    /**
     * 更换台号   待做是否重新计时
     *
     * @return
     */
    @PostMapping("/changeTable")
    @RepeatSubmit
    public Result changeTable(@RequestBody ChangeTableDto Dto) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        Dto.setShopId(shopId);
        Dto.setStaffId(user.getUserId());
        return Result.success(openTableService.changeTable(Dto));
    }

    /**
     * 更换台号   待做是否重新计时
     *
     * @return
     */
    @PostMapping("/changeTableRemark")
    @RepeatSubmit
    public Result changeRemark(@RequestBody ChangDto  changDto) {

        openTableService.changeRemark(changDto);
        return Result.success();
    }

    /**
     * 更换台号   待做是否重新计时
     *
     * @return
     */
    @PostMapping("/changeTableTime")
    @RepeatSubmit
    public Result changeTableTime(@RequestBody @Validated DeskTimeDto dto) {
        openTableService.changeTableTime(dto);
        return Result.success();
    }

    /**
     * 当前店铺所有可用桌号
     *
     * @param shopId
     * @return
     */
    @GetMapping("/tableList/{shopId}")
    @ApiOperation(value = "开桌暂停", httpMethod = "GET")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderNumber", value = "订单编号", dataType = "String", required = true),
            @ApiImplicitParam(name = "stopStatus", value = "暂停状态 0关闭 1 开启   ", dataType = "String", required = true),
    })
    public Result changeTable(@PathVariable("shopId") String shopId) {
        TTablenumber tTablenumber = new TTablenumber();
        tTablenumber.setBelong(shopId);
        tTablenumber.setStatus(TablenumberState.NO_LOCK.getValue());
        List<TTablenumber> tTablenumbers = tTablenumberService.selectTTablenumberList(tTablenumber);
        return Result.success(tTablenumbers);
    }

    /**
     * 实现暂定计时的功能 开始暂停 和结束暂停接口
     * 1 记录什么时候点的暂停
     * 2 取消暂停的时候计算中间的间隔,减去开始时间
     * 传 1 是开启暂停 0是结束暂停
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/stopTime/{orderNumber}/{stopStatus}")
    @ApiOperation(value = "开桌暂停", httpMethod = "GET")
    @ApiImplicitParams(value = {
            @ApiImplicitParam(name = "orderNumber", value = "订单编号", dataType = "String", required = true),
            @ApiImplicitParam(name = "stopStatus", value = "暂停状态 0关闭 1 开启   ", dataType = "String", required = true),
    })
    public Result stopTime(@PathVariable("orderNumber") String orderNumber,
                           @PathVariable("stopStatus") String stopStatus) {
        Integer i = openTableService.stopTableTime(orderNumber, stopStatus);
        String s = i == 0 ? "操作失败" : "操作成功";
        return Result.success(s);
    }



    /**
     * 个人结账操作
     *
     * @return
     */
    @GetMapping("/checkout/{memberId}/{deskingId}")
    @ApiOperation(value = "结账操作", httpMethod = "GET")
    public Result checkout(@ApiParam("会员id") @PathVariable("memberId") Long memberId,
                           @ApiParam("开桌id") @PathVariable("deskingId") Long deskId) {
        openTableService.checkout(memberId,deskId);
        return Result.success();
    }


    /**
     * 结束桌子
     *
     * @return
     */
    @GetMapping("/coverDesk/{deskingId}")
    @ApiOperation(value = "结账操作", httpMethod = "GET")
    public AjaxResult coverDesk(@ApiParam("开桌id") @PathVariable("deskingId") Long deskingId) {

        return openTableService.coverDesk(deskingId);
    }
    /**
     * 整体结账操作
     *
     * @return
     */
    @GetMapping("/checkoutAll/{deskingId}")
    @ApiOperation(value = "结账操作", httpMethod = "GET")
    public Result checkoutAll(
                           @ApiParam("开桌id") @PathVariable("deskingId") Long deskId) {


        openTableService.checkoutAll(deskId);

        return Result.success();
    }

    /**
     * 整体结账操作
     *
     * @return
     */
    @GetMapping("/suspend")
    @ApiOperation(value = "暂停计时", httpMethod = "GET")
    public Result suspend( @Validated  SuspendDto  suspendDto) {


        openTableService.suspend(suspendDto);

        return Result.success();
    }


    /**
     * 定时刷新请求任务
     *
     * @return
     */
    @GetMapping("/caclDesk/{orderSn}")
    @ApiOperation(value = "费用计算", httpMethod = "GET")
    public Result caclDesk( @PathVariable String orderSn) {
        chargTask.caclDesk(orderSn);
        return Result.success();
    }
}
